package com.yy.QSManage.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.yy.QSManage.dao.FaSysGenMapper;
import com.yy.QSManage.exception.ServiceException;
import com.yy.QSManage.generator.VelocityInitializer;
import com.yy.QSManage.generator.VelocityUtils;
import com.yy.QSManage.model.dto.GenCodeDto;
import com.yy.QSManage.model.dto.GenColumDto;
import com.yy.QSManage.model.entity.FaSysGen;
import com.yy.QSManage.service.FaSysGenService;
import com.yy.QSManage.service.base.impl.BaseServiceImpl;
import netscape.javascript.JSObject;
import org.apache.commons.io.FileUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service
public class FaSysGenServiceImpl extends BaseServiceImpl<FaSysGenMapper, FaSysGen> implements FaSysGenService {

    @Autowired
    FaSysGenMapper genMapper;

    @Override
    public void generateCode(String id) {
        List<HashMap<String,String>> codeList = generateCodeList(id);
        generateCode(codeList, new GenCodeDto());
    }

    @Override
    public void generateCode(List<HashMap<String,String>> codeList, GenCodeDto genCodeDto) {
        if(!genCodeDto.getCover()){
            // 检查代码是否已生成
            for (HashMap<String, String> code : codeList) {
                File file = new File(code.get("path"));
                if (file.exists()) {
                    throw new ServiceException("同名代码已存在：" + code.get("path"));
                }
            }
        }
        // 代码写入文件
        for (HashMap<String, String> code : codeList) {
            String path = code.get("path");
            String codeJosn = code.get("code");
            try
            {
                FileUtils.writeStringToFile(new File(path), codeJosn, "UTF-8");
            }
            catch (IOException e)
            {
                throw new ServiceException("渲染模板失败，表名：" + path);
            }
        }
    }

    @Override
    public String generateCodePreview(String id) {
        List<HashMap<String,String>> codeList = generateCodeList(id);
        return new JSONArray(codeList).toString();
    }

    /**
     * 生成模版代码map
     * @param id
     * @return
     */
    public List<HashMap<String,String>> generateCodeList(String id){
        FaSysGen genInfo = genMapper.getGenInfo(id);
        // 下划字段线改驼峰
        List<GenColumDto> genColums = genInfo.getGenColums();
        for (GenColumDto genColum : genColums) {
            genColum.setFieldHump(StrUtil.toCamelCase(genColum.getField()));
        }

        // 初始化代码生成程序
        VelocityInitializer.initVelocity();
        // 设置模板变量
        VelocityContext context = VelocityUtils.prepareContext(genInfo);
        // 获取模板列表
        List<String> templates = VelocityUtils.getTemplateList();
        List<HashMap<String,String>> codeList = new ArrayList<>();
        for (String template : templates)
        {
            // 渲染模板
            StringWriter sw = new StringWriter();
            Template tpl = Velocity.getTemplate(template, "UTF-8");
            tpl.merge(context, sw);
            String path = getGenPath(genInfo, template);
            HashMap<String,String> codeMap = new HashMap<>();
            codeMap.put("path", path);
            codeMap.put("code", sw.toString());
            codeList.add(codeMap);
        }
        return codeList;
    }

    /**
     * 获取代码生成地址
     * @param genInfo
     * @param template
     * @return
     */
    public static String getGenPath(FaSysGen genInfo, String template)
    {
        return System.getProperty("user.dir") + File.separator + "src" + File.separator + VelocityUtils.getFileName(genInfo, template);
    }
}
